﻿using System;
using System.Collections.Generic;
using Lists = Algoritmia.DataStructures.Lists;

namespace Algoritmia.Problems.CoinChange
{
    public class MoneyChangeStateSpace3 : IMoneyChangeForwardStateSpace<Tuple<int, int>, int>
    {
        private readonly int _Q;
        private readonly Lists.IList<int> _values;
        private readonly int _n;

        public MoneyChangeStateSpace3(int Q, Lists.IList<int> values)
        {
            _Q = Q;
            _values = values;
            _n = values.Count;
        }
               
        #region Implementation of IForwardStateSpace<Tuple<int,int>,int>

        public Tuple<int, int> Decide(Tuple<int, int> state, int decision)
        {
            var q = state.Item1;
            var n = state.Item2;
            return new Tuple<int, int>(q + decision * _values[n],n+1);
        }

        public IEnumerable<int> Decisions(Tuple<int, int> state)
        {
            var q = state.Item1;
            var n = state.Item2;
            if ( n < _n)
            {
                var upper = (_Q - q)/_values[n];
                for(int i = 0; i <= upper; i++)
                {
                    yield return i;
                }
            }
        }

        public IEnumerable<Tuple<int, int>> InitialStates
        {
            get { yield return new Tuple<int, int>(0,0);}
        }

        public bool IsFinal(Tuple<int, int> state)
        {
            return state.Item1 == _Q && state.Item2 == _n;
        }

        #endregion
    }
}
